function varargout = MpMapperGUI(varargin)
% MPMAPPERGUI MATLAB code for MpMapperGUI.fig
%      MPMAPPERGUI, by itself, creates a new MPMAPPERGUI or raises the existing
%      singleton*.
%
%      H = MPMAPPERGUI returns the handle to a new MPMAPPERGUI or the handle to
%      the existing singleton*.
%
%      MPMAPPERGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MPMAPPERGUI.M with the given input arguments.
%
%      MPMAPPERGUI('Property','Value',...) creates a new MPMAPPERGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before MpMapperGUI_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to MpMapperGUI_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help MpMapperGUI

% Last Modified by GUIDE v2.5 11-Jul-2012 09:12:09

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @MpMapperGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @MpMapperGUI_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT




% --- Executes just before MpMapperGUI is made visible.
function MpMapperGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to MpMapperGUI (see VARARGIN)

% Choose default command line output for MpMapperGUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);

% UIWAIT makes MpMapperGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% vnr
resetFields(hObject, handles);

%------[SET UP GUI DISPLAY]------------------------------------------------
%------[CENTER WINDOW]-----------------------------------------------------


% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
movegui(gcf, 'center')
guidata(hObject, handles)



% --- Outputs from this function are returned to the command line.
function varargout = MpMapperGUI_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

%------[NEI Logo Banner and background_axis]---------------------------------------------------

% --- Executes during object creation, after setting all properties.
function axis_33_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axis_33 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axis_33
axes(hObject);
banner = imread('NEI_logo_1.png');
banner = imresize(banner, 3);
imagesc(banner);
axis off;
guidata(hObject, handles);


% --- Executes during object creation, after setting all properties.
function axis_34_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axis_34 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axis_34
axes(hObject);
imagesc(imread('GUI Background.jpg'));
uistack(hObject, 'bottom');
axis off;
guidata(hObject, handles);


% --- Executes during object creation, after setting all properties.
function edit_workdir_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_workdir (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background_axis on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in pushbutton_workdir.
function pushbutton_workdir_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_workdir (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
patientFolderPath = uigetdir('.', 'Please select working directory.');
[patientBeginPath patientFolder] = fileparts(patientFolderPath);
set(handles.edit_workdir,'String',patientFolder);
handles.patientFolderPath = patientFolderPath;
guidata(hObject, handles);



function edit_redpath_Callback(hObject, eventdata, handles)
% hObject    handle to edit_redpath (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_redpath as text
%        str2double(get(hObject,'String')) returns contents of edit_redpath as a double


% --- Executes during object creation, after setting all properties.
function edit_redpath_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_redpath (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background_axis on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbutton_redpath.
function pushbutton_redpath_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_redpath (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Check if patient folder was chosen
if ~exist(get(handles.edit_workdir, 'String'), 'file')
    errordlg('Please select a working directory')
end
% Change to directory to patient directory
cd(handles.patientFolderPath);
% Have user select the red image file
redImFiles = uigetfile('*', 'Please select RED image');
%Set edit box to display name of image chosen
set(handles.edit_redpath, 'String', redImFiles);

% Ask User about IR or Red Refl so information can be stored in the excel
choiceRed = questdlg('Did you use Red Refl or IR?','IR or Red Refl','Red RGB', 'IR', 'Red RGB');
switch choiceRed
    case 'Red RGB'
        backgroundAdjustmentIm = 'Red RGB';
    case 'IR'
        backgroundAdjustmentIm = 'IR';        
end
%Create handles to be recalled in other functions
handles.redImFiles = redImFiles; 
handles.backgroundAdjustmentIm = backgroundAdjustmentIm;
guidata(hObject, handles); %Save handles for later use


% --- Executes on selection change in im_selector.
function im_selector_Callback(hObject, eventdata, handles)
% hObject    handle to im_selector (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns im_selector contents as cell array
%        contents{get(hObject,'Value')} returns selected item from im_selector

% Check if patient folder was chosen
if ~exist(get(handles.edit_workdir, 'String'), 'file')
    errordlg('Please select a working directory')
end
% Check to make sure red image was selected
if ~exist(handles.redImFiles); % Check to make sure red image was selected
    errordlg('Please select a red image')
end
% Change to directory to patient directory
workDir = handles.patientFolderPath;
cd(workDir);
%Determine which method was selected in the drop down menu.
VALUE = get(hObject, 'Value'); %Each string has a specific index value in menu
methodChoices = get(hObject, 'String');
selectedMethod = methodChoices{VALUE}; %Use valued index 
%Read in image files or paths based on selected method
if strcmp(selectedMethod, 'Directory Select')
    blueImgFiles = uigetdir(workDir, 'Please select BLUE directory');
    otherImgFiles = uigetdir(workDir, 'Please select Yellow, Green, or Other directory');
elseif strcmp(selectedMethod, 'Single Images') 
    blueImgFiles = uigetfile('*.tif', 'Please select BLUE image');
    otherImgFiles = uigetfile('*.tif', 'Please select OTHER image');
elseif strcmp(selectedMethod, 'BLUE vs YELLOW') 
   blueImgFiles = [workDir filesep 'BLUE'];
   otherImgFiles = [workDir filesep 'YELLOW'];
elseif strcmp(selectedMethod, 'BLUE vs GREEN') 
   blueImgFiles = [workDir filesep 'BLUE'];
   otherImgFiles = [workDir filesep 'GREEN'];
elseif strcmp(selectedMethod, 'Choose Method')
    errordlg('Please choose a method from the dropdown menu')
    return;
else
    errordlg('Drop down menu malfunction')
end

% Ask User about directory method chosen
if strcmp(selectedMethod, 'Directory Select')
    infoSelectedMethod = inputdlg('Please type directories chosen in the following format: 1st directory color chosen vs 2nd directory color chosen.');
    infoSelectedMethod = char(infoSelectedMethod);
elseif strcmp(selectedMethod, 'Single Images')
    infoSelectedMethod = inputdlg('Please type images chosen in the following format: 1st image color vs 2nd image color');
    infoSelectedMethod = char(infoSelectedMethod);
else
    infoSelectedMethod = char(selectedMethod);
end

% Store blue image file, other image file, and selected method in handles 
%to be recalled in other functions 
handles.blueImFiles = blueImgFiles; 
handles.otherImFiles = otherImgFiles;
handles.selectedMethod = selectedMethod;
handles.infoSelectedMethod = infoSelectedMethod;
guidata(hObject, handles)






% --- Executes during object creation, after setting all properties.
function im_selector_CreateFcn(hObject, eventdata, handles)
% hObject    handle to im_selector (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background_axis on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
 

% --- Executes on button press in pushbutton_defmacregion.
function pushbutton_defmacregion_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_defmacregion (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Check if patient folder was chosen
if ~exist(get(handles.edit_workdir, 'String'), 'file')
    errordlg('Please select a working directory')
end
% Check to make sure red image was selected
if ~exist(handles.redImFiles); % Check to make sure red image was selected
    errordlg('Please select a red image')
end
% Check to make sure a method was chosen

% Change to directory to patient directory
cd(handles.patientFolderPath);

% Determine which method was used and apply pre-op on blue, other, and red.
% Pre-op for single image blue and other is a conversion of images from 3D
% to 2D and to class double. Pre-op for blue and other directory images
% consists of averaging the images in the directory. Pre-op for the red
% image is similar to the pre-op for single image analysis. Store the blue,
% red, and other image in the handles to be recalled later.

%Pre-op red image
handles.redIm = computeDirAvgImage(handles.redImFiles, '*.tif', 'file');

if strcmp(handles.selectedMethod, 'Single Images')
    %Pre-op single images
    handles.blueIm = computeDirAvgImage(handles.blueImFiles, '*.tif', 'file');
    handles.otherIm = computeDirAvgImage(handles.otherImFiles, '*.tif', 'file');
else
    %Pre-op directory methods
    handles.blueIm = computeDirAvgImage(handles.blueImFiles, '*.tif', 'dir');
    handles.otherIm = computeDirAvgImage(handles.otherImFiles, '*.tif', 'dir');
end

%Check to make sure images are all the same size. This is essential to the
%algorithm's functionality.

if size(handles.blueIm) ~= size(handles.otherIm)
    errordlg('Please choose blue and other images that are registered together and have the same size')
elseif size(handles.blueIm) ~= size(handles.redIm)
    errordlg('Please choose blue and red images that are registered together and have the same size')
end

% PICK FOVEA

% Find approximate center of fovea with box_cent_fov and blue image.
[fovRow, fovCol] = box_cent_fov(handles.blueIm); 
close;

% Highlight a larger region that was selected by box_cent_fov so user see
% the selection
temp = handles.blueIm;
temp(fovRow-2:fovRow+2,fovCol-2:fovCol+2) = 1;

% Maximize figure size and insert blue image
scrsz = get(0, 'Screensize');
figure('Position', [scrsz(1) scrsz(2) scrsz(3) scrsz(4)]), imagesc(imnorm(temp));
axis image;
axis off; colormap(gray);

% Ask user whether they want to change position of center of fovea
choice = questdlg('Does the fovea position require adjustment?','ADJUST FOVEA LOCATION?','YES','NO','NO');
switch choice
    case 'YES'
        imagesc(imnorm(temp));
        title('Please select a suitable point for the fovea.');
        axis image;
        axis off; colormap(gray); 
        [fov_col, fov_row] = ginput(1);
        fovRow = round(fov_row);
        fovCol = round(fov_col);
        handles.macRegionChoice = 'Yes';
    case 'NO'
        handles.macRegionChoice = 'No';
        
end

%Establish handles of fovRow and fovCol so they can be used by other
%functions. Use these definitions from now on

handles.fovRow = fovRow;
handles.fovCol = fovCol;


% SELECT OPTIC DISK
% Have user select closest point on optic disk to fovea.
temp = handles.blueIm;
temp(handles.fovRow-2:handles.fovRow+2,handles.fovCol-2:handles.fovCol+2) = 1;
imagesc(imnorm(temp));
title('Please select the point on the optic disk closest to the fovea');
axis image;
axis off; colormap(gray);
[opDiskCol, opDiskRow] = ginput(1);
close;

%Establish handles of opdisk row and col
opDiskRow = round(opDiskRow); 
opDiskCol = round(opDiskCol);
handles.opDiskRow = opDiskRow;
handles.opDiskCol = opDiskCol;


% DEFINE MACULAR REGION (ESTIMATED TO BE 4 DEGREES OFF OF VISUAL AXIS)

degreesFromFov = 4;
[ imageFeatures ] =...
    computeMacularData(fovRow, fovCol, opDiskRow, opDiskCol, handles.blueIm, degreesFromFov);

handles.macRadius = imageFeatures.macRadius;
handles.iMacBoundary = imageFeatures.iMacBoundary;
handles.iMacRegion = imageFeatures.iMacRegion;
handles.iNonMacRegion = imageFeatures.iNonMacRegion;

axes(handles.axes1); %Display selection on axis
    

handles.imageMap = containers.Map;

% Add name/image data pairs to map container used by image selection menus.
% Note: use of cell is workaround for restrictions on map contents.

blueImCell = cell(1);
blueImCell{1} = handles.blueIm;

otherImCell = cell(1);
otherImCell{1} = handles.otherIm;

redImCell = cell(1);
redImCell{1} = handles.redIm;

macboundaryBlueIm = handles.blueIm;
macboundaryBlueIm(handles.iMacBoundary) = 1;
macboundaryBlueImCell = cell(1);
macboundaryBlueImCell{1} = macboundaryBlueIm;


handles.imageMap('BLUE AVERAGE') = blueImCell;
handles.imageMap('YELLOW (GREEN) AVERAGE') = otherImCell;
handles.imageMap('RED REFL. IMAGE') = redImCell;
handles.imageMap('MACULAR BOUNDARY (BLUE AVERAGE)') = macboundaryBlueImCell;

tmp = handles.imageMap('MACULAR BOUNDARY (BLUE AVERAGE)');
imshow(tmp{1});

imageMapKeys = handles.imageMap.keys;
leftPopupItems  = {'LEFT' imageMapKeys{:} };
rightPopupItems = {'RIGHT' imageMapKeys{:} };

rightMenuSelection = getCurrentMenuSelection(handles.popupmenu_right);

set(handles.popupmenu_left,'String', leftPopupItems);
set(handles.popupmenu_right,'String', rightPopupItems);

indx = findIndexInStringList(leftPopupItems, 'MACULAR BOUNDARY (BLUE AVERAGE)');
set(handles.popupmenu_left,'Value', indx);
indx = findIndexInStringList(rightPopupItems, rightMenuSelection);
set(handles.popupmenu_right,'Value', indx);

handles.definedMacularRegion = true;

set(hObject, 'BackgroundColor', 'g')

guidata(hObject, handles);

%-----[END OF pushbutton_defmacregion_Callback]----------------------------


% --- Executes on button press in pushbutton_defcontrastregions.
function pushbutton_defcontrastregions_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_defcontrastregions (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%-----[Selection of Contrast Regions]--------------------------------------

if ~handles.definedMacularRegion
    errorStr = 'Please DEFINE MACULAR REGION before running this step.';
    errordlg(errorStr, 'ERROR');
    return;
end

% Normalize the images in case we plan on using high-contrast pixel
% selection

imageSet.blueIm = handles.blueIm;
imageSet.otherIm = handles.otherIm;
imageSet.redIm = handles.redIm;
imageFeatures.iMacBoundary = handles.iMacBoundary;
imageFeatures.iMacRegion = handles.iMacRegion;

handles.normalizedImSet = imNormalizer(imageSet, imageFeatures, 1/2);


% (2) SELECT HIGH-CONTRAST PIXEL SET USE IN PARAMETER TUNING
% 
% % Below code is for 3 contrast region selection. Please have this below
% % code uncommented up to the line that states "code for 4 degree selection" if you want
% % to use 3 contrast selection. Comment the 4 degree code too.
% % Have the user indicate a set of high contrast regions ... 
% numContrastRegions = 3; %Number of contrast regions selected
% 
% %Highlight the fovea and the 4 degree fovea circle
% temp = handles.yellowNormalizedIm;
% temp(handles.fovRow-2:handles.fovRow+2,handles.fovCol-2:handles.fovCol+2) = 1;
% temp(handles.iMacBoundary) = 1;
% 
% %Maximize figure and obtain user input from figure window.
% scrsz = get(0, 'ScreenSize');
% figure('Position',[scrsz(1) scrsz(2) scrsz(3) scrsz(4)]) , imagesc(temp);
% title(['Please indicate ' num2str(numContrastRegions) ' suitable high contrast regions within the red boundary.']);
% axis image;
% axis off; colormap(gray);
% 
% [x, y] = ginput(numContrastRegions); %User select region
% close;
% 
% x = round(x); y = round(y);
% 
% %Size of image contrast regions selected on
% imgSize = size(handles.otherAvgIm);
% %Boxsize
% boxsize = 15;
% handles.iContrastRegion = [];
% index_set = contrastBoxIndex(x, y, numContrastRegions, boxsize, imgSize);
% handles.iContrastRegion = [handles.iContrastRegion index_set'];

% Below is code for 4 degree selection. Please uncomment this code to use
% this method.
% Define contrast region along the macular boundary.
handles.iContrastRegion = handles.iMacBoundary;


axes(handles.axes1);

contrastRegionsOther = handles.normalizedImSet.otherIm;
contrastRegionsOther(handles.iContrastRegion) = 1;
contrastRegionsOtherCell = cell(1);
contrastRegionsOtherCell{1} = contrastRegionsOther;

handles.imageMap('CONTRAST REGIONS (YELLOW/GREEN NORM.)') = contrastRegionsOtherCell;

tmp = handles.imageMap('CONTRAST REGIONS (YELLOW/GREEN NORM.)');
imshow(tmp{1});

imageMapKeys = handles.imageMap.keys;
leftPopupItems  = {'LEFT' imageMapKeys{:} };
rightPopupItems = {'RIGHT' imageMapKeys{:} };

rightMenuSelection = getCurrentMenuSelection(handles.popupmenu_right);

set(handles.popupmenu_left,'String', leftPopupItems);
set(handles.popupmenu_right,'String', rightPopupItems);

indx = findIndexInStringList(leftPopupItems, 'CONTRAST REGIONS (YELLOW/GREEN NORM.)');
set(handles.popupmenu_left,'Value', indx);
indx = findIndexInStringList(rightPopupItems, rightMenuSelection);
set(handles.popupmenu_right,'Value', indx);

handles.setHighContrastRegions = true;

set(hObject, 'BackgroundColor', 'g')


guidata(hObject, handles);

%-----[END OF pushbutton_defcontrastregions_Callback]----------------------


% --- Executes on button press in pushbutton_runpigmentmap.
function pushbutton_runpigmentmap_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_runpigmentmap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%-----[Run background_axis Correction]------------------------------------------

if ~handles.setHighContrastRegions
    errorStr = 'Please NORMALIZE AND SELECT CONTRAST REGIONS before running this step.';
    errordlg(errorStr, 'ERROR');
    return;
end

% Set up imageSet and imageFeatures to be used in functions
imageSet.blueIm = handles.blueIm;
imageSet.otherIm = handles.otherIm;
imageSet.redIm = handles.redIm;

imageFeatures.fovRow = handles.fovRow;
imageFeatures.fovCol = handles.fovCol;
imageFeatures.iMacRegion = handles.iMacRegion;
imageFeatures.iNonMacRegion = handles.iNonMacRegion;
imageFeatures.iContrastRegion = handles.iContrastRegion;
imageFeatures.iMacBoundary = handles.iMacBoundary;
imageFeatures.macRadius = handles.macRadius;
imageFeatures.iContrastRegion = handles.iContrastRegion;

% Normalize images for user selected center since they only need to be
% normalized once.
normalizedImSet = imNormalizer(imageSet, imageFeatures, 1/2);

% Run mac pig algorithm for variable, uniform, and no correction.

[variableRatioIm variableRgbMpMap variableQuantityData plotDataVarCorrected]...
    = runMacPigAlgorithm(normalizedImSet, imageFeatures, 'Variable', 'User',...
    'Norm');

[uniformRatioIm uniformRgbMpMap uniformQuantityData plotDataUniformCorrected]...
    = runMacPigAlgorithm(normalizedImSet, imageFeatures, 'Uniform', 'User',...
    'Norm');

[ uncorrectedRatioIm uncorrectedRgbMpMap uncorrectedQuantityData plotDataUncorrectedRatio]...
    = runMacPigAlgorithm(normalizedImSet, imageFeatures, 'Uncorrected', 'User',...
    'Norm');

% Re-find centers based on the macular pigment map
[variableMapFovRow variableMapFovCol] = findMpMapCenter(variableRatioIm, imageFeatures);
[uniformMapFovRow uniformMapFovCol] = findMpMapCenter(uniformRatioIm, imageFeatures);
[uncorrectedMapFovRow uncorrectedMapFovCol] = findMpMapCenter(uncorrectedRatioIm, imageFeatures);

% Re-compute macular data for the new centers. This will be used to re-run 
% the algorithm.
degreesFromFov = 4;
% Variable Macular Data and redefined imageFeatures
[imageFeaturesVariable] = computeImageFeatures...
    (variableMapFovRow, variableMapFovCol, handles.opDiskRow,...
    handles.opDiskCol, imageSet.blueIm, degreesFromFov);
% Redefine the iContrast Regions. Use the same contrast regions as the user
% selected center used
imageFeaturesVariable.iContrastRegion = imageFeatures.iContrastRegion;

% Uniform Macular Data and redefined imageFeatures
[ imageFeaturesUniform] = computeMacularData...
    (uniformMapFovRow, uniformMapFovCol, handles.opDiskRow,...
    handles.opDiskCol, imageSet.blueIm, degreesFromFov);
% Redefine the iContrast Regions. Use the same contrast regions as the user
% selected center used
imageFeaturesUniform.iContrastRegion = imageFeatures.iContrastRegion;

% Uncorrected Macular Data and redefined imageFeatures
[imageFeaturesUncorrected] = computeMacularData...
    (uncorrectedMapFovRow, uncorrectedMapFovCol, handles.opDiskRow,...
    handles.opDiskCol, imageSet.blueIm, degreesFromFov);
% Uncorrected Macular Data and redefined imageFeatures
imageFeaturesUncorrected.iContrastRegion = imageFeatures.iContrastRegion;

%Re-run the algorithm with the new macular data
%Variable
[ variableMpRatioIm variableMpRgbMpMap variableMpQuantityData variableMpPlotData]...
    = runMacPigAlgorithm( imageSet, imageFeaturesVariable, 'Variable', 'Mp',...
    'Raw');
% Uniform
[ uniformMpRatioIm uniformMpRgbMpMap uniformMpQuantityData uniformMpPlotData]...
    = runMacPigAlgorithm( imageSet, imageFeaturesUniform, 'Uniform', 'Mp',...
    'Raw');

[ uncorrectedMpRatioIm uncorrectedMpRgbMpMap uncorrectedMpQuantityData uncorrectdMpPlotData]...
    = runMacPigAlgorithm( imageSet, imageFeaturesUncorrected, 'Uncorrected', 'Mp',...
    'Raw');

% Mix the quantatative data with the qualitative data from the GUI.
% Qualitative data includes patient ID, method chosen, and red image used.

% Generate a cell structure containing the quality data. This is universal
% for all corrections
[patientBeginPath patientFolder] = fileparts(handles.patientFolderPath);
qualityData = {'Patient ID', 'Method', 'Red Image Used'; patientFolder,...
    handles.selectedMethod, handles.backgroundAdjustmentIm};

% Combine the quality with the quantity data to form a full data set. Store
% this in a structure object that will be used later to write out multiple
% sheets to an excel file

fullData.userVariable = [qualityData, variableQuantityData];
fullData.userUniform = [qualityData, uniformQuantityData];
fullData.userUncorrected = [qualityData, uncorrectedQuantityData];
fullData.mpVariable = [qualityData, variableMpQuantityData];
fullData.mpUniform = [qualityData, uniformMpQuantityData];
fullData.mpUncorrected = [qualityData, uncorrectedMpQuantityData];

% Store the data from the analysis in the TEMP folder to that patient
[patientBeginPath patientFolder] = fileparts(handles.patientFolderPath);
infoStorage = [handles.patientFolderPath filesep 'TEMP'];
cd(infoStorage); %Change to the new direct

% Name the excel workbook that the data will be saved in and generate the
% list of sheet names.
excelWorkbookName = [char(patientFolder) '_data.xls'];
worksheetNames = fieldnames(fullData);
% Create an excel sheet
for i = 1:length(worksheetNames)
    fieldData = getfield(fullData, char(worksheetNames(i)));
    sheetName = worksheetNames(i);
    xlswrite(excelWorkbookName, fieldData, char(sheetName));
end

% Save macular pigment maps for both user and MP center, uniform and
% variable
imwrite(variableRgbMpMap, [patientFolder '_Variable Map_user_center.tif'], 'tif');
imwrite(uniformRgbMpMap, [patientFolder '_Uniform Map_user_center.tif'], 'tif');
imwrite(variableMpRgbMpMap, [patientFolder '_Variable Map_MP_center.tif'], 'tif');
imwrite(uniformMpRgbMpMap, [patientFolder '_Uniform Map_MP_center.tif'], 'tif');
    
% Save the user center macular pigment plot
overlayFig = figure('Menu', 'none', 'Toolbar', 'none', 'Units', 'normalized', 'Position',...
    [-1000 -1000 1 1]);
plot(plotDataVarCorrected, 'r')
hold on
plot(plotDataUniformCorrected, 'b')
plot(plotDataUncorrectedRatio, 'g')
legend('Red Refl Corr', 'Baseline Corr', 'Uncorrected', 'Location', 'BestOutside')
xlabel('Relative Distance from Fovea in Pixels');
ylabel('Radial Average of MP Map');
title('User Center Graph');
hold off
saveas(overlayFig, [patientFolder '_Rscan_user_center.tif']);
delete(overlayFig);

% Save the MP center macular pigment plot
overlayFig = figure('Menu', 'none', 'Toolbar', 'none', 'Units', 'normalized', 'Position',...
    [-1000 -1000 1 1]);
plot(variableMpPlotData, 'r')
hold on
plot(uniformMpPlotData, 'b')
plot(uncorrectdMpPlotData, 'g')
legend('Red Refl Corr', 'Baseline Corr', 'Uncorrected', 'Location', 'BestOutside')
xlabel('Relative Distance from Fovea in Pixels');
ylabel('Radial Average of MP Map');
title('MP Center Graph');
hold off
saveas(overlayFig, [patientFolder '_Rscan_MP_center.tif']);
delete(overlayFig);
 
% Display variable MP on axis and update imageMap
axes(handles.axes2);
varCorrectedRatioCell = cell(1);
varCorrectedRatioCell{1} = handles.varCorrectedRatio;
varBlueCorrected = cell(1);
varBlueCorrected{1} = varCorrectedImageSet.blueIm;
varOtherCorrected = cell(1);
varOtherCorrected{1} = varCorrectedImageSet.otherIm;

handles.imageMap('RED REFL. CORRECTED BLUE/YELLOW(GREEN) RATIO') = varCorrectedRatioCell;
handles.imageMap('RED REFL. CORRECTED BLUE') = varBlueCorrected;
handles.imageMap('RED REFL. CORRECTED YELLOW(GREEN)') = varOtherCorrected;

tmp = handles.imageMap('RED REFL. CORRECTED BLUE/YELLOW(GREEN) RATIO');
imshow(tmp{1});

handles.imageMap('UNIFORM BG. CORRECTED BLUE/YELLOW(GREEN) RATIO') = uniformCorrectedRatioCell;
handles.imageMap('UNIFORM BG. CORRECTED BLUE') = uniformBlueCorrectedCell;
handles.imageMap('UNIFORM BG. CORRECTED YELLOW(GREEN)') = uniformOtherCorrectedCell;

%-----------[UPDATE IMAGE SELECTION POPUP MENUS]--------------------------------

imageMapKeys = handles.imageMap.keys;
leftPopupItems  = {'LEFT' imageMapKeys{:} };
rightPopupItems = {'RIGHT' imageMapKeys{:} };

leftMenuSelection = getCurrentMenuSelection(handles.popupmenu_left);

set(handles.popupmenu_left,'String', leftPopupItems);
set(handles.popupmenu_right,'String', rightPopupItems);

indx = findIndexInStringList(leftPopupItems, leftMenuSelection);
set(handles.popupmenu_left,'Value', indx);
indx = findIndexInStringList(rightPopupItems, 'RED REFL. CORRECTED BLUE/YELLOW(GREEN) RATIO');
set(handles.popupmenu_right,'Value', indx);

%-----------[DISPLAY MP MAP RADIAL AVERAGE PLOTS]-------------------------------

% Display user selected center plot in axes
axes(handles.axes3);
plot(plotDataVarCorrected, 'r')
    hold on
    plot(plotDataUniformCorrected, 'b')
    plot(plotDataUncorrectedRatio, 'g')
    legend('Red Refl Corr', 'Baseline Corr', 'Uncorrected', 'Location', 'BestOutside')
    xlabel('Relative Distance from Fovea in Pixels');
    ylabel('Radial Average of MP Map');
    title('User Selected Center');
    hold off

set(hObject, 'BackgroundColor', 'g')

guidata(hObject,handles);

% --- Executes on selection change in popupmenu_left.
function popupmenu_left_Callback(hObject, ~, handles)
% hObject    handle to popupmenu_left (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_left contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_left
val = get(hObject,'Value');
string_list = get(hObject,'String');
selected_string = string_list{val}; % Convert from cell array to string
if ( strcmp(selected_string,'LEFT') || strcmp(selected_string,' ') )
    cla(handles.axes1);
% elseif ( strcmp(selected_string, 'RED REFL. CORRECTED BLUE/YELLOW(GREEN) RATIO') || strcmp(selected_string, 'UNIFORM BG. CORRECTED BLUE/YELLOW(GREEN) RATIO'))
%     axes(handles.axes1);
%     tmp = handles.imageMap(selected_string);
%     tmp = imcrop(tmp, [0.25*size(tmp,1) 0.25*size(tmp,2) 0.75*size(tmp,1) 0.75*size(tmp,2)]);
%     imshow(tmp{1});

else
    axes(handles.axes1);
    tmp = handles.imageMap(selected_string);
    tmp = imshow(tmp{1});
end



% --- Executes during object creation, after setting all properties.
function popupmenu_left_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_left (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background_axis on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in popupmenu_right.
function popupmenu_right_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu_right (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_right contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_right
val = get(hObject,'Value');
string_list = get(hObject,'String');
selected_string = string_list{val}; % Convert from cell array to string
if ( strcmp(selected_string,'RIGHT') || strcmp(selected_string,' ') )
    cla(handles.axes2);
else
    axes(handles.axes2);
    tmp = handles.imageMap(selected_string);
    imshow(tmp{1});
end


% --- Executes during object creation, after setting all properties.
function popupmenu_right_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_right (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background_axis on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --------------------------------------------------------------------
function Save_All_ClickedCallback(hObject, eventdata, handles)
% hObject    handle to Save_Graphs (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global redReflVar baseCorrVar ContourPlotData
%Globals must be defined in both functions utilizing them
ORIG_DIR = pwd;


WORK_DIR = get(handles.edit_workdir,'String');
if WORK_DIR(end) == '/'
    WORK_DIR = WORK_DIR(1:end-1);
end
cd([WORK_DIR filesep 'TEMP'])
% imwrite(handles.blueAvgIm,'blue_avg.tif','TIFF');
% imwrite(handles.yel_avg,'yel_avg.tif','TIFF');
% imwrite(handles.corrected_blue_yel_ratio, 'corrected_blue_yel_ratio.tif','TIFF');

%Generate Patient Identifier
[patientPath patientFolder] = fileparts(WORK_DIR);
patientFolder = num2str(patientFolder);


%Save all important images
imwrite(handles.blue_ubgcorrected,[patientFolder '_blue_ubgcorrected.tif'],'TIFF');
imwrite(handles.blue_corrected,[patientFolder '_blue_rrcorrected.tif'],'TIFF');
imwrite(handles.ubgcorrected_blue_yel_ratio,[patientFolder '_ubgcorrected_blue_yel_ratio.tif'],'TIFF');
imwrite(handles.corrected_blue_yel_ratio,[patientFolder '_rrcorrected_blue_yel_ratio.tif'],'TIFF');

%Save Both graphs and overlay graph
%Red Reflection Correction Graph (comes from axes3)
redReflFig = figure('Menu', 'none', 'Toolbar', 'none', 'Units', 'normalized',...
    'Position', [-1000 -1000 1 1]);
plotData_rrfcorrected_blue_yel_ratio = rscan(handles.corrected_blue_yel_ratio,'xavg',...
    handles.fovCol,'yavg',handles.fovRow,'rlim',handles.macRadius,'dispflag',0);
plot(plotData_rrfcorrected_blue_yel_ratio, 'r');
xlabel('Relative Distance from Fovea');
ylabel('Radial Average of MP Map');
title(['Red Reflection Graph Total Variation = ' redReflVar])
saveas(redReflFig, [patientFolder '_RedReflPlot.tif']);
delete(redReflFig);

%Baseline Correction Graph (comes from axes4)
baseCorrFig = figure('Menu', 'none', 'Toolbar', 'none', 'Units', 'normalized', 'Position',...
    [-1000 -1000 1 1]);
plotData_ubgcorrected_blue_yel_ratio = rscan(handles.ubgcorrected_blue_yel_ratio,'xavg',...
    handles.fovCol,'yavg',handles.fovRow,'rlim',handles.macRadius,'dispflag',0);
plot(plotData_ubgcorrected_blue_yel_ratio, 'b');
xlabel('Relative Distance from Fovea');
ylabel('Radial Average of MP Map');
title(['Baseline Correction Graph Total Variation = ' baseCorrVar])
saveas(baseCorrFig, [patientFolder '_BaseCorrPlot.tif']);
delete(baseCorrFig);

%Overlay graphs
overlayFig = figure('Menu', 'none', 'Toolbar', 'none', 'Units', 'normalized', 'Position',...
    [-1000 -1000 1 1]);
plot(plotData_rrfcorrected_blue_yel_ratio, 'r')
hold on
plot(plotData_ubgcorrected_blue_yel_ratio, 'b')
legend('Red Refl Corr', 'Baseline Corr')
xlabel('Relative Distance from Fovea');
ylabel('Radial Average of MP Map');
title('Overlay Graph');
hold off
saveas(overlayFig, [patientFolder '_OverlayPlot.tif']);
delete(overlayFig);

%ContourPlot
C_Plot = figure('Menu', 'none', 'Toolbar', 'none', 'Position',...
    [-1000 -1000 1 1]);
contour(ContourPlotData);
colormap jet
colorbar
xlabel('Beta Values * 100')
ylabel('Alpha Values * 100')
saveas(C_Plot, [patientFolder '_ContourPlot.tif'])
delete(C_Plot)

cd(ORIG_DIR);


% --- Executes on button press in debugger.
function debugger_Callback(hObject, eventdata, handles)
% hObject    handle to debugger (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
keyboard
disp('This button has been clicked. You can now access data in the command window of the current state of the GUI')



% --- Executes on button press in pushbutton_reset.
function pushbutton_reset_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_reset (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
resetFields(hObject, handles);


%-------------[helper functions]-------------------------------------------

function resetFields(hObject, handles)
set(handles.edit_workdir,'String','Patient Folder');
set(handles.edit_redpath,'String','Red Reflection or IR');
cla(handles.axes1);
cla(handles.axes2);
cla(handles.axes3);
set(handles.axes3,'Visible','off');
cla(handles.axes4);
set(handles.axes4,'Visible','off');
cla(handles.axes5);
set(handles.axes5, 'Visible', 'off');
set(handles.popupmenu_left,'Value', 1);
set(handles.popupmenu_left,'String', {'LEFT' });
set(handles.popupmenu_right,'Value', 1);
set(handles.popupmenu_right,'String', {'RIGHT' });
handles.definedMacularRegion = false;
handles.setHighContrastRegions = false;
set(handles.im_selector, 'Value', 1);
set(handles.pushbutton_defmacregion, 'BackgroundColor', [0.9412    0.9412    0.9412])
set(handles.pushbutton_defcontrastregions, 'BackgroundColor', [0.9412    0.9412    0.9412])
set(handles.pushbutton_runpigmentmap, 'BackgroundColor', [0.9412    0.9412    0.9412])
guidata(hObject,handles);



function indx = findIndexInStringList(strlist, str)
L = length(strlist);
indxset = 1 : L;
matchvec = strcmp(str,strlist);
if ( any(matchvec) )
    indx = indxset(matchvec);
else
    indx = -1;
end

function str = getCurrentMenuSelection(menu)
items = get(menu,'String'); 
indx = get(menu,'Value');
disp(['number of items in menu: ' num2str(length(items)) '(indx=' num2str(indx) ')']);
str = items(indx);
